package cn.chiship.framework.common.config.aspect;

import cn.chiship.framework.common.annotation.DataScope;
import cn.chiship.framework.common.enums.DataScopeEnum;
import cn.chiship.framework.common.pojo.dto.BaseQueryEntityDto;
import cn.chiship.sdk.cache.service.UserCacheService;
import cn.chiship.sdk.cache.vo.CacheDepartmentVo;
import cn.chiship.sdk.cache.vo.CacheRoleVo;
import cn.chiship.sdk.cache.vo.CacheUserVO;
import cn.chiship.sdk.core.util.StringUtil;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;


/**
 * 数据过滤处理
 *
 * @author lj
 */
@Aspect
@Component
public class DataScopeAspect {

    /**
     * 数据权限过滤关键字
     */
    public static final String DATA_SCOPE = "dataScope";

    @Resource
    private UserCacheService userCacheService;

    @Before("@annotation(controllerDataScope)")
    public void doBefore(JoinPoint point, DataScope controllerDataScope){
        clearDataScope(point);
        handleDataScope(point, controllerDataScope);
    }

    protected void handleDataScope(final JoinPoint joinPoint, DataScope controllerDataScope) {

        // 获取当前的用户
        CacheUserVO userVO = userCacheService.getUser();
        if (!StringUtil.isNull(userVO)) {
            dataScopeFilter(joinPoint, userVO);
        }
    }

    /**
     * 数据范围过滤
     *
     * @param joinPoint   切点
     * @param cacheUserVO 用户
     */
    public static void dataScopeFilter(JoinPoint joinPoint, CacheUserVO cacheUserVO) {

        List<String> userIds = new ArrayList<>();
        List<String> orgIds = new ArrayList<>();

        if (cacheUserVO.getAdmin()) {
            return;
        }

        Object params = joinPoint.getArgs()[joinPoint.getArgs().length - 1];
        if (!StringUtil.isNull(params) && params instanceof BaseQueryEntityDto) {
            BaseQueryEntityDto baseEntity = (BaseQueryEntityDto) params;
            baseEntity.setDataScopeAll(false);


            for (CacheRoleVo role : cacheUserVO.getCacheRoleVos()) {
                Byte dataScope = role.getDataScope();
                if (DataScopeEnum.DATA_SCOPE_ALL.getType().equals(dataScope)) {
                    baseEntity.setDataScopeAll(true);
                    break;
                } else if (DataScopeEnum.DATA_SCOPE_CUSTOM.getType().equals(dataScope)) {

                } else if (DataScopeEnum.DATA_SCOPE_ORG.getType().equals(dataScope)) {

                } else if (DataScopeEnum.DATA_SCOPE_ORG_AND_CHILD.getType().equals(dataScope)) {

                } else if (DataScopeEnum.DATA_SCOPE_DEPT.getType().equals(dataScope)) {
                    CacheDepartmentVo departmentVo = cacheUserVO.getCacheDepartmentVo();
                    if (!StringUtil.isNull(departmentVo)) {
                        orgIds.add(StringUtil.getString(departmentVo.getId()));
                    } else {
                        orgIds.add("-1");
                    }
                } else if (DataScopeEnum.DATA_SCOPE_DEPT_AND_CHILD.getType().equals(dataScope)) {

                } else if (DataScopeEnum.DATA_SCOPE_SELF.getType().equals(dataScope)) {
                    userIds.add(StringUtil.getString(cacheUserVO.getId()));
                }
            }

            baseEntity.setUserIds(userIds);
            baseEntity.setOrgIds(orgIds);
            baseEntity.getParams().put("orgIds", orgIds);
            baseEntity.getParams().put("userIds", userIds);

        }

    }

    /**
     * 拼接权限sql前先清空params.dataScope参数防止注入
     */
    private void clearDataScope(final JoinPoint joinPoint) {
        Object params = joinPoint.getArgs()[joinPoint.getArgs().length - 1];
        if (!StringUtil.isNull(params) && params instanceof BaseQueryEntityDto) {
            BaseQueryEntityDto baseEntity = (BaseQueryEntityDto) params;
            baseEntity.getParams().put(DATA_SCOPE, "");
        }
    }
}
